package com.pointcircle.estate.server.framework.web.api;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pointcircle.core.IRepository;
import com.pointcircle.core.util.DateUtils;
import com.pointcircle.core.web.EntityVo;
import com.pointcircle.core.web.FormVo;
import com.pointcircle.core.web.IAddRest;
import com.pointcircle.core.web.IFindByIdRest;
import com.pointcircle.core.web.RestResponseElement;
import com.pointcircle.core.web.RestResponseList;
import com.pointcircle.estate.server.framework.entity.BatchType;
import com.pointcircle.estate.server.framework.entity.CheckQualityBatch;
import com.pointcircle.estate.server.framework.entity.CheckQualityCc;
import com.pointcircle.estate.server.framework.entity.CheckQualityProblem;
import com.pointcircle.estate.server.framework.entity.CheckQualityReinspect;
import com.pointcircle.estate.server.framework.entity.CheckQualityRepair;
import com.pointcircle.estate.server.framework.entity.ProblemClass;
import com.pointcircle.estate.server.framework.entity.ProblemStatus;
import com.pointcircle.estate.server.framework.repository.BuildingRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityBatchRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityCcRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityProblemRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityReinspectRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityRepairRepository;
import com.pointcircle.estate.server.framework.repository.ContractorRepository;
import com.pointcircle.estate.server.framework.repository.FloorRepository;
import com.pointcircle.estate.server.framework.repository.HouseRepository;
import com.pointcircle.estate.server.framework.repository.ProblemClassRepository;
import com.pointcircle.estate.server.framework.repository.ProblemRepository;
import com.pointcircle.estate.server.framework.repository.UnitRepository;
import com.pointcircle.estate.server.framework.web.api.QualityMeasureCheckQualityProblemApi.ProblemSendBack.Photo;

import lombok.Getter;
import lombok.Setter;
import net.coobird.thumbnailator.Thumbnails;


@RestController
@RequestMapping("/api/checkQualityProblem")
public class CheckQualityProblemApi implements
	IFindByIdRest<CheckQualityProblem, String, CheckQualityProblemApi.CheckQualityProblemEntityVo>,
	IAddRest<CheckQualityProblem, String, CheckQualityProblemApi.CheckQualityProblemEntityVo, CheckQualityProblemApi.CheckQualityProblemFormVo> {
	
	@Value("${web.upload-path.img}")
	private String uploadPathImg;
	
	@Value("${web.img-url}")
	private String webImgUrl;
	
	@Autowired
	private CheckQualityProblemRepository repository;
	
	@Autowired
	private CheckQualityBatchRepository checkQualityBatchRepository;
	
	@Autowired
	private ProblemClassRepository problemClassRepository;
	
	@Autowired
	private BuildingRepository buildingRepository;
	
	@Autowired
	private UnitRepository unitRepository; 
	
	@Autowired
	private FloorRepository floorRepository;
	
	@Autowired
	private HouseRepository houseRepository;
	
	@Autowired
	private ProblemRepository problemRepository;
	
	@Autowired
	private com.pointcircle.core.repository.UserRepository userRepository;
	
	@Autowired
	private ContractorRepository contractorRepository;
	
	@Autowired
	private CheckQualityRepairRepository checkQualityRepairRepository;
	
	@Autowired
	private CheckQualityReinspectRepository checkQualityReinspectRepository;
	
	@Autowired
	private CheckQualityCcRepository checkQualityCcRepository;
	
	public class CheckQualityProblemEntityVo extends EntityVo<CheckQualityProblem, String> {

		public CheckQualityProblemEntityVo(CheckQualityProblem entity) {
			super(entity);
		}
		
		private String repairId = null;
		private List<String> reinspectIds = new LinkedList<String>();
		private List<String> ccIds = new LinkedList<String>();
		
		@JsonProperty(value = "updateTimestamp")
		public Long getUpdateTimestamp() {
			if(entity.getUpdateTime() != null) {
				return entity.getUpdateTime().getTime();
			} else {
				Date dateReturn = entity.getRegistDate();
				if(entity.getCloseDate() != null && dateReturn.before(entity.getCloseDate())) {
					dateReturn = entity.getCloseDate();
				}
				if(entity.getRepairDate() != null && dateReturn.before(entity.getRepairDate())) {
					dateReturn = entity.getRepairDate();
				}
				if(entity.getReinspectCompletedDate() != null && dateReturn.before(entity.getReinspectCompletedDate())) {
					dateReturn = entity.getReinspectCompletedDate();
				}
				if(entity.getSentBackDate() != null &&  dateReturn.before(entity.getSentBackDate())) {
					dateReturn = entity.getSentBackDate();
				}
				return dateReturn.getTime();
			}
		}
		@JsonProperty("batchId")
		public String getBatchId() {
			return entity.getBatchId();
		}
		@JsonProperty("batchType")
		public BatchType getBatchType() {
			return entity.getBatchType();
		}
		@JsonProperty("itemId")
		public String getItemId() {
			return entity.getItemId();
		}
		@JsonProperty("contractorId")
		public String getContractorId() {
			return entity.getContractorId();
		}
		@JsonProperty("descId")
		public String getDescId() {
			return entity.getDescId();
		}
		@JsonProperty("remark")
		public String getRemark() {
			return entity.getRemark();
		}
		@JsonProperty("imageFile")
		public String getImageFile() {
			if(StringUtils.isEmpty(entity.getImageFile())) {
				return "[]";
			} else {
				return entity.getImageFile();
			}
		}
		@JsonProperty("smallImageFile")
		public String getSmallImageFile() {
			if(StringUtils.isEmpty(entity.getSmallImageFile())) {
				return "[]";
			} else {
				return entity.getSmallImageFile();
			}
		}
		@JsonProperty("bidSectionId")
		public String getBidSectionId() {
			return entity.getCheckQualityBatch().getBidSectionId();
		}
		@JsonProperty("buildingId")
		public String getBuildingId() {
			return entity.getBuildingId();
		}
		@JsonProperty("buildingName")
		public String getBuildingName() {
			if(entity.getBuildingId() != null) {
				return entity.getBuilding().getBuildingName();
			}
			return null;
		}
		@JsonProperty("unitId")
		public String getUnitId() {
			return entity.getUnitId();
		}
		@JsonProperty("unitName")
		public String getUnitName() {
			if(entity.getUnitId() != null) {
				return entity.getUnit().getUnitName();
			}
			return null;
		}
		@JsonProperty("floorId")
		public String getFloorId() {
			return entity.getFloorId();
		}
		@JsonProperty("floorName")
		public String getFloorName() {
			if(entity.getFloorId() != null) {
				return entity.getFloor().getFloorName();
			}
			return null;
		}
		@JsonProperty("roomId")
		public String getRoomId() {
			return entity.getRoomId();
		}
		@JsonProperty("roomName")
		public String getRoomName() {
			if(entity.getRoomId() != null) {
				return entity.getHouse().getHouseName();
			}
			return null;
		}
		@JsonProperty("houseTypeId")
		public String getHouseTypeId() {
			if(entity.getRoomId() != null) {
				return entity.getHouse().getHouseTypeId();
			} else {
				return null;
			}
		}
		@JsonProperty("place")
		public String getPlace() {
			return entity.getPlace();
		}
		@JsonProperty("status")
		public ProblemStatus getStatus() {
			return entity.getStatus();
		}
		@JsonProperty("emergencyDegree")
		public String getEmergencyDegree() {
			return entity.getEmergencyDegree();
		}
		@JsonProperty("registBy")
		public String getRegistBy() {
			return entity.getRegistByUserId();
		}
		@JsonProperty("registDate")
		public Long getRegistDate() {
			return entity.getRegistDate() != null ? entity.getRegistDate().getTime() : null;
		}
		@JsonProperty("repairBy")
		public String getRepairBy() {
			return entity.getRepairByUserId();
		}
		@JsonProperty("repairDeadline")
		public Long getRepairDeadline() {
			return entity.getRepairDeadline() != null ? entity.getRepairDeadline().getTime() : null;
		}
		@JsonProperty("repairDate")
		public Long getRepairDate() {
			return entity.getRepairDate() != null ? entity.getRepairDate().getTime() : null;
		}
		@JsonProperty("repairRemark")
		public String getRepairRemark() {
			return entity.getRepairRemark();
		}
		@JsonProperty("repairImageFile")
		public String getRepairImageFile() {
			if(StringUtils.isEmpty(entity.getRepairImageFile())) {
				return "[]";
			} else {
				return entity.getRepairImageFile();
			}
		}
		@JsonProperty("smallRepairImageFile")
		public String getSmallRepairImageFile() {
			if(StringUtils.isEmpty(entity.getSmallRepairImageFile())) {
				return "[]";
			} else {
				return entity.getSmallRepairImageFile();
			}
		}
		@JsonProperty("problemValues")
		public String getProblemValues() {
			if(StringUtils.isEmpty(entity.getProblemValues())) {
				return "[]";
			} else {
				return entity.getProblemValues();
			}
		}
		@JsonProperty("sentBackBy")
		public String sentBackBy() {
			return entity.getSendBackByUserId();
		}
		@JsonProperty("sentBackDate")
		public Long getSentBackDate() {
			return entity.getSentBackDate() != null ? entity.getSentBackDate().getTime() : null;
		}
		@JsonProperty("sentBackTimes")
		public Integer getSentBackTimes() {
			return entity.getSentBackTimes();
		}
		@JsonProperty("sentBackRemark")
		public String getSentBackRemark() {
			return entity.getSentBackRemark();
		}
		@JsonProperty("sentBackImageFile")
		public String getSentBackImageFile() {
			if(StringUtils.isEmpty(entity.getSentBackImageFile())) {
				return "[]";
			} else {
				return entity.getSentBackImageFile();
			}
		}
		@JsonProperty("smallSentBackImageFile")
		public String getSmallSentBackImageFile() {
			if(StringUtils.isEmpty(entity.getSmallSentBackImageFile())) {
				return "[]";
			} else {
				return entity.getSmallSentBackImageFile();
			}
		}
		@JsonProperty("reinspectBy")
		public String getReinspectBy() {
			return entity.getReinspectByUserId();
		}
		@JsonProperty("reinspectImageFile")
		public String getReinspectImageFile() {
			if(StringUtils.isEmpty(entity.getReinspectImageFile())) {
				return "[]";
			} else {
				return entity.getReinspectImageFile();
			}
		}
		@JsonProperty("smallReinspectImageFile")
		public String getSmallReinspectImageFile() {
			if(StringUtils.isEmpty(entity.getSmallReinspectImageFile())) {
				return "[]";
			} else {
				return entity.getSmallReinspectImageFile();
			}
		}
		@JsonProperty("reinspectRemark")
		public String getReinspectRemark() {
			return entity.getReinspectRemark();
		}
		@JsonProperty("reinspectCompletedDate")
		public Long getReinspectCompletedDate() {
			return entity.getReinspectCompletedDate() != null ? entity.getReinspectCompletedDate().getTime() : null;
		}
		@JsonProperty("closeDate")
		public Long getCloseDate() {
			return entity.getCloseDate() != null ? entity.getCloseDate().getTime() : null;
		}
		@JsonProperty("closeReason")
		public String getCloseReason() {
			return entity.getCloseReason();
		}
		@JsonProperty("drawingFile")
		public String getDrawingFile() {
			if(StringUtils.isEmpty(entity.getDrawingFile())) {
				return "[]";
			} else {
				return entity.getDrawingFile();
			}
		}
		public void setCcIds(List<String> ccIds) {
			this.ccIds = ccIds;
		}
		@JsonProperty("ccs")
		public String getCcs() {
			JSONArray array = new JSONArray(ccIds);
			return array.toString();
		}
		public void setRepairId(String repairId) {
			this.repairId = repairId;
		}
		@JsonProperty("repairId")
		public String getRepairId() {
			return this.repairId;
		}
		public void setReinspectIds(List<String> reinspectIds) {
			this.reinspectIds = reinspectIds;
		}
		@JsonProperty("reinspectIds")
		public String getReinspectIds() {
			JSONArray array = new JSONArray(reinspectIds);
			return array.toString();
		}
	}

	@Getter
	@Setter
	public static class CheckQualityProblemFormVo extends FormVo<String> {
		@Getter
		@Setter
		public static class ProblemValue {
			private String x;
			private String y;
		}
		@Getter
		@Setter
		public static class Photo {
			private String url;
		}
		@NotBlank(message = "批次不能为空")
		private String batchId;
		private String buildingId;
		private String unitId;
		private String floorId;
		private String houseId;
		private String place;
		@NotBlank(message = "检查项不能为空")
		private String problemClassId;
		private String problemId;
		@NotBlank(message = "登记人不能为空")
		private String registBy;
		private String remark;
		private String emergencyDegree;
		private int days;
		private String contractorId;
		@Size(message = "整改人不能为空")
		private List<String> repairs = new LinkedList<String>();
		@Size(message = "复验人不能为空")
		private List<String> reinspects = new LinkedList<String>();
		private List<String> ccs = new LinkedList<String>();
		private List<Photo> photos = new LinkedList<Photo>();
		private List<ProblemValue> problemValues = new LinkedList<ProblemValue>();
	}
	
	@Getter
	@Setter
	public static class ProblemSendBack {
		@Getter
		@Setter
		public static class Photo {
			private String url;
		}
		@NotBlank(message = "检查项不能为空")
		private String checkQualityProblemId;
		@NotBlank(message = "退回人不能为空")
		private String sendBackUserId;
		private String sendBackRemark;
		private List<Photo> photos = new LinkedList<Photo>();
	}

	@Override
	public IRepository<CheckQualityProblem, String> getRepository() {
		return repository;
	}
	
	@PostMapping("regist")
	public RestResponseElement regist (
				@RequestParam(value = "batchId") String batchId,
				@RequestParam(value = "buildingId", required = false) String buildingId,
				@RequestParam(value = "unitId", required = false) String unitId,
				@RequestParam(value = "floorId", required = false) String floorId,
				@RequestParam(value = "houseId", required = false) String houseId,
				@RequestParam(value = "place", defaultValue = "") String place,
				@RequestParam(value = "problemClassId") String problemClassId,
				@RequestParam(value = "problemId", required = false) String problemId,
				@RequestParam(value = "registUserId") String registUserId,
				@RequestParam(value = "registRemark", defaultValue = "") String registRemark,
				@RequestParam(value = "registEmergencyDegree", defaultValue = "一般") String registEmergencyDegree,
				@RequestParam(value = "registDays", defaultValue = "0") int registDays,
				@RequestParam(value = "repairContractorId") String repairContractorId,
				@RequestParam(value = "repairUserIds") List<String> repairUserIds,
				@RequestParam(value = "reinspectUserIds") List<String> reinspectUserIds,
				@RequestParam(value = "ccUserIds", required = false) List<String> ccUserIds,
				@RequestParam(value = "photos", required = false) List<MultipartFile> multipartFiles,
				@RequestParam(value = "pointsX", required = false) List<String> pointsX,
				@RequestParam(value = "pointsY", required = false) List<String> pointsY) throws IOException, JSONException {
					
		CheckQualityProblem checkQualityProblem = new CheckQualityProblem();
		CheckQualityBatch checkQualityBatch = checkQualityBatchRepository.getOne(batchId);
		ProblemClass rootProblemClass = problemClassRepository.getOne(problemClassId).getParentProblemClass();
		checkQualityProblem.setCheckQualityBatch(checkQualityBatch);
		checkQualityProblem.setBatchType(checkQualityBatch.getBatchType());
		if(rootProblemClass.getProblemClassName().equals("工程亮点")) {
			checkQualityProblem.setStatus(ProblemStatus.已通过);
			if(buildingId != null) {
				checkQualityProblem.setBuilding(buildingRepository.findById(buildingId).orElse(null));
			}
			if(unitId != null) {
				checkQualityProblem.setUnit(unitRepository.findById(unitId).orElse(null));
			}
			if(floorId != null) {
				checkQualityProblem.setFloor(floorRepository.findById(floorId).orElse(null));
			}
			if(houseId != null) {
				checkQualityProblem.setHouse(houseRepository.findById(houseId).orElse(null));
			}
			checkQualityProblem.setProblemValues("[]");
			if(pointsX != null) {
				JSONArray array = new JSONArray();
				for(int i = 0; i < pointsX.size(); i++) {
					String x = pointsX.get(i);
					String y = pointsY.get(i);
					JSONObject object = new JSONObject();
					object.put("x", x);
					object.put("y", y);
					array.put(object);
				}
				checkQualityProblem.setProblemValues(array.toString());
			}
			checkQualityProblem.setPlace(place);
			checkQualityProblem.setProblemClass(problemClassRepository.findById(problemClassId).orElse(null));
			if(problemId != null) {
				checkQualityProblem.setProblem(problemRepository.findById(problemId).orElse(null));
			}
			checkQualityProblem.setRegistBy(userRepository.findById(registUserId).orElse(null));
			checkQualityProblem.setRepairBy(userRepository.findById(registUserId).orElse(null));
			checkQualityProblem.setReinspectBy(userRepository.findById(registUserId).orElse(null));
			checkQualityProblem.setRegistDate(new Date());
			checkQualityProblem.setRepairDate(new Date());
			checkQualityProblem.setReinspectCompletedDate(new Date());
			checkQualityProblem.setRemark(registRemark);
			checkQualityProblem.setEmergencyDegree("一般");
			if(registDays == 0) {
				registDays = checkQualityBatch.getRepairDeadline();
			}
			checkQualityProblem.setRepairDeadline(DateUtils.addDay(DateUtils.today(), registDays));
			
			JSONArray imageFileJson = new JSONArray();
			JSONArray smallImageFileJson = new JSONArray();
			for(MultipartFile multipartFile : multipartFiles) {
				String fileName = UUID.randomUUID().toString() + ".jpg";
				String filePath = uploadPathImg + "/" + fileName;
				File f = new File(filePath);
				FileOutputStream fos = new FileOutputStream(f);
				InputStream is = multipartFile.getInputStream();
				byte[] bytes = new byte[1024];
				do {
					int len = is.read(bytes);
					if(len == -1) {
						break;
					}
					fos.write(bytes, 0, len);
				} while(true);
				fos.close();
				JSONObject json = new JSONObject();
				String url = webImgUrl + fileName;
				json.put("url", url);
				imageFileJson.put(json);
				
				String smallFileName = "small_" + fileName;
				String smallFilePath = uploadPathImg + "/" + smallFileName;
				Thumbnails.of(filePath) 
		        	.scale(0.2f) 
		        	.outputQuality(0.5f) 
		        	.toFile(smallFilePath);
				json = new JSONObject();
				url = webImgUrl + smallFileName;
				json.put("url", url);
				smallImageFileJson.put(json);
			}
			checkQualityProblem.setImageFile(imageFileJson.toString());
			checkQualityProblem.setSmallImageFile(smallImageFileJson.toString());
			this.getRepository().saveAndFlush(checkQualityProblem);
			
		} else {
			checkQualityProblem.setStatus(ProblemStatus.待整改);
			if(buildingId != null) {
				checkQualityProblem.setBuilding(buildingRepository.findById(buildingId).orElse(null));
			}
			if(unitId != null) {
				checkQualityProblem.setUnit(unitRepository.findById(unitId).orElse(null));
			}
			if(floorId != null) {
				checkQualityProblem.setFloor(floorRepository.findById(floorId).orElse(null));
			}
			if(houseId != null) {
				checkQualityProblem.setHouse(houseRepository.findById(houseId).orElse(null));
			}
			checkQualityProblem.setProblemValues("[]");
			if(pointsX != null) {
				JSONArray array = new JSONArray();
				for(int i = 0; i < pointsX.size(); i++) {
					String x = pointsX.get(i);
					String y = pointsY.get(i);
					JSONObject object = new JSONObject();
					object.put("x", x);
					object.put("y", y);
					array.put(object);
				}
				checkQualityProblem.setProblemValues(array.toString());
			}
			checkQualityProblem.setPlace(place);
			checkQualityProblem.setProblemClass(problemClassRepository.findOne(problemClassId));
			if(problemId != null) {
				checkQualityProblem.setProblem(problemRepository.findOne(problemId));
			}
			checkQualityProblem.setRegistBy(userRepository.findOne(registUserId));
			checkQualityProblem.setRegistDate(new Date());
			checkQualityProblem.setRemark(registRemark);
			checkQualityProblem.setEmergencyDegree(registEmergencyDegree);
			if(registDays == 0) {
				registDays = checkQualityBatch.getRepairDeadline();
			}
			checkQualityProblem.setRepairDeadline(DateUtils.addDay(DateUtils.today(), registDays));
			checkQualityProblem.setContractor(contractorRepository.findOne(repairContractorId));
			JSONArray imageFileJson = new JSONArray();
			JSONArray smallImageFileJson = new JSONArray();
			for(MultipartFile multipartFile : multipartFiles) {
				String fileName = UUID.randomUUID().toString() + ".jpg";
				String filePath = uploadPathImg + "/" + fileName;
				File f = new File(filePath);
				FileOutputStream fos = new FileOutputStream(f);
				InputStream is = multipartFile.getInputStream();
				byte[] bytes = new byte[1024];
				do {
					int len = is.read(bytes);
					if(len == -1) {
						break;
					}
					fos.write(bytes, 0, len);
				} while(true);
				fos.close();
				JSONObject json = new JSONObject();
				String url = webImgUrl + fileName;
				json.put("url", url);
				imageFileJson.put(json);
				
				String smallFileName = "small_" + fileName;
				String smallFilePath = uploadPathImg + "/" + smallFileName;
				Thumbnails.of(filePath) 
	        		.scale(0.2f) 
		        	.outputQuality(0.5f) 
		        	.toFile(smallFilePath);
				json = new JSONObject();
				url = webImgUrl + smallFileName;
				json.put("url", url);
				smallImageFileJson.put(json);
			}
			checkQualityProblem.setImageFile(imageFileJson.toString());
			checkQualityProblem.setSmallImageFile(smallImageFileJson.toString());
			this.getRepository().saveAndFlush(checkQualityProblem);
			for(String repairUserId : repairUserIds) {
				CheckQualityRepair repair = new CheckQualityRepair();
				repair.setCheckQualityProblem(checkQualityProblem);
				repair.setRepair(userRepository.findOne(repairUserId));
				checkQualityRepairRepository.saveAndFlush(repair);
			}
			for(String reinspectUserId : reinspectUserIds) {
				CheckQualityReinspect reinspect = new CheckQualityReinspect();
				reinspect.setCheckQualityProblem(checkQualityProblem);
				reinspect.setReinspect(userRepository.findOne(reinspectUserId));
				checkQualityReinspectRepository.saveAndFlush(reinspect);
			}
		}
		
		if(ccUserIds != null) {
			for(String ccUserId : ccUserIds) {
				CheckQualityCc cc = new CheckQualityCc();
				cc.setCheckQualityProblem(checkQualityProblem);
				cc.setCc(userRepository.findOne(ccUserId));
				cc.setType("被抄送");
				checkQualityCcRepository.saveAndFlush(cc);
			}
		}
		CheckQualityProblemEntityVo vo = new CheckQualityProblemEntityVo(checkQualityProblem);
		vo.setCcIds(checkQualityCcRepository.findCcIdsByCheckQualityProblemId(checkQualityProblem.getId()));
		RestResponseElement response = new RestResponseElement();
		response.setElement(vo);
		return response;
	}
	
	@GetMapping("findByBatchId")
	public RestResponseList findByBatchId(
		@RequestParam("batchId") String batchId) {
		CheckQualityBatch batch = checkQualityBatchRepository.findOne(batchId);
		List<CheckQualityProblem> problems = repository.findByCheckQualityBatch(batch);
		Map<String, List<String>> unprocessedCcMap = new HashMap<String, List<String>>();
		checkQualityCcRepository.findByCheckQualityProblemIn(problems)
			.forEach((cc) -> {
				List<String> ccIds = unprocessedCcMap.get(cc.getCheckqualityProblemId());
				if(ccIds == null) {
					ccIds = new LinkedList<String>();
					unprocessedCcMap.put(cc.getCheckqualityProblemId(), ccIds);
				}
				ccIds.add(cc.getCcId());
			});
		List<CheckQualityProblemEntityVo> entityVoList = problems.stream().map((problem) -> {
				CheckQualityProblemEntityVo vo = new CheckQualityProblemEntityVo(problem);
				vo.setCcIds(unprocessedCcMap.get(problem.getId()));
				return vo;
			}).collect(Collectors.toList());
		RestResponseList respone = new RestResponseList();
		respone.setList(entityVoList);
		return respone;
	}
	
	@PostMapping("problemClose")
	public RestResponseElement problemClose (
			@RequestParam(value = "checkQualityProblemId") String checkQualityProblemId,
			@RequestParam(value = "closeRemark") String closeRemark) {
		CheckQualityProblem checkQualityProblem = repository.findOne(checkQualityProblemId);
		checkQualityProblem.setStatus(ProblemStatus.已关闭);
		checkQualityProblem.setCloseDate(new Date());
		checkQualityProblem.setCloseReason(closeRemark);
		this.getRepository().saveAndFlush(checkQualityProblem);
		CheckQualityProblemEntityVo entityVo = new CheckQualityProblemEntityVo(checkQualityProblem);
		entityVo.setCcIds(checkQualityCcRepository.findCcIdsByCheckQualityProblemId(checkQualityProblem.getId()));
		RestResponseElement response = new RestResponseElement();
		response.setElement(entityVo);
		return response;
	}
	
	@PostMapping("problemRepair")
	public RestResponseElement problemRepair (
			@RequestParam(value = "checkQualityProblemId") String checkQualityProblemId,
			@RequestParam(value = "repairUserId") String repairUserId,
			@RequestParam(value = "repairRemark", required = false) String repairRemark,
			@RequestParam(value = "photos", required = false) List<String> photos) 
				throws IOException, JSONException {
		CheckQualityProblem checkQualityProblem = repository.findOne(checkQualityProblemId);
		checkQualityProblem.setStatus(ProblemStatus.待复验);
		checkQualityProblem.setRepairBy(userRepository.findOne(repairUserId));
		checkQualityProblem.setRepairRemark(repairRemark);
		checkQualityProblem.setRepairDate(new Date());
		
		/*JSONArray imageFileJson = new JSONArray();
		JSONArray smallImageFileJson = new JSONArray();
		for(MultipartFile multipartFile : multipartFiles) {
			String fileName = UUID.randomUUID().toString() + ".jpg";
			String filePath = uploadPathImg + "/" + fileName;
			File f = new File(filePath);
			FileOutputStream fos = new FileOutputStream(f);
			InputStream is = multipartFile.getInputStream();
			byte[] bytes = new byte[1024];
			do {
				int len = is.read(bytes);
				if(len == -1) {
					break;
				}
				fos.write(bytes, 0, len);
			} while(true);
			fos.close();
			JSONObject json = new JSONObject();
			String url = webImgUrl + fileName;
			json.put("url", url);
			imageFileJson.put(json);
			
			String smallFileName = "small_" + fileName;
			String smallFilePath = uploadPathImg + "/" + smallFileName;
			Thumbnails.of(filePath) 
	        	.scale(0.2f) 
	        	.outputQuality(0.5f) 
	        	.toFile(smallFilePath);
			json = new JSONObject();
			url = webImgUrl + smallFileName;
			json.put("url", url);
			smallImageFileJson.put(json);
		}
		checkQualityProblem.setSmallRepairImageFile(smallImageFileJson.toString());
		checkQualityProblem.setRepairImageFile(imageFileJson.toString());*/
		
		JSONArray imageFileJson = new JSONArray();
		for(String photo: photos) {
			JSONObject json = new JSONObject();
			json.put("url", photo);
			imageFileJson.put(json);
		}
		checkQualityProblem.setRepairImageFile(imageFileJson.toString());
		this.getRepository().saveAndFlush(checkQualityProblem);
		CheckQualityProblemEntityVo entityVo = new CheckQualityProblemEntityVo(checkQualityProblem);
		entityVo.setCcIds(checkQualityCcRepository.findCcIdsByCheckQualityProblemId(checkQualityProblem.getId()));
		RestResponseElement response = new RestResponseElement();
		response.setElement(entityVo);
		return response;
	}
	
	@PostMapping("problemReinspect")
	public RestResponseElement problemReinspect (
			@RequestParam(value = "checkQualityProblemId") String checkQualityProblemId,
			@RequestParam(value = "reinspectUserId") String reinspectUserId,
			@RequestParam(value = "reinspectRemark", required = false) String reinspectRemark,
			@RequestParam(value = "photos", required = false) List<String> photos)
					throws IOException, JSONException {
		CheckQualityProblem checkQualityProblem = repository.findOne(checkQualityProblemId);
		checkQualityProblem.setStatus(ProblemStatus.已通过);
		checkQualityProblem.setReinspectBy(userRepository.findOne(reinspectUserId));
		checkQualityProblem.setReinspectCompletedDate(new Date());
		checkQualityProblem.setReinspectRemark(reinspectRemark);
		JSONArray imageFileJson = new JSONArray();
		for(String photo: photos) {
			JSONObject json = new JSONObject();
			json.put("url", photo);
			imageFileJson.put(json);
		}
		this.getRepository().saveAndFlush(checkQualityProblem);
		CheckQualityProblemEntityVo entityVo = new CheckQualityProblemEntityVo(checkQualityProblem);
		entityVo.setCcIds(checkQualityCcRepository.findCcIdsByCheckQualityProblemId(checkQualityProblem.getId()));
		RestResponseElement response = new RestResponseElement();
		response.setElement(entityVo);
		return response;
	}
	
	@PostMapping("problemSendBack")
	public RestResponseElement problemSendBack (
			/*@RequestParam(value = "checkQualityProblemId") String checkQualityProblemId,
			@RequestParam(value = "sendBackUserId") String sendBackUserId,
			@RequestParam(value = "sendBackRemark", required = false) String sendBackRemark,
			@RequestParam(value = "photos", required = false) List<MultipartFile> multipartFiles*/
			@Valid @RequestBody ProblemSendBack problemSendBack) throws IOException, JSONException {
		ObjectMapper mapper = new ObjectMapper();
		CheckQualityProblem checkQualityProblem = repository.findOne(problemSendBack.checkQualityProblemId);
		checkQualityProblem.setStatus(ProblemStatus.待整改);
		checkQualityProblem.setSendBackBy(userRepository.findOne(problemSendBack.sendBackUserId));
		if(checkQualityProblem.getSentBackTimes() == null) {
			checkQualityProblem.setSentBackTimes(1);
		}else {
			checkQualityProblem.setSentBackTimes(checkQualityProblem.getSentBackTimes() + 1);
		}
		checkQualityProblem.setSentBackDate(new Date());
		checkQualityProblem.setSentBackRemark(problemSendBack.sendBackRemark);
		checkQualityProblem.setSentBackImageFile(mapper.writeValueAsString(problemSendBack.photos));
		for(com.pointcircle.estate.server.framework.web.api.CheckQualityProblemApi.ProblemSendBack.Photo photo : problemSendBack.photos) {
			photo.setUrl(photo.url + "?x-oss-process=image/resize,m_fixed,h_80,w_80");
		}
		checkQualityProblem.setSmallSentBackImageFile(mapper.writeValueAsString(problemSendBack.photos));
		this.getRepository().saveAndFlush(checkQualityProblem);
		CheckQualityProblemEntityVo entityVo = new CheckQualityProblemEntityVo(checkQualityProblem);
		entityVo.setCcIds(checkQualityCcRepository.findCcIdsByCheckQualityProblemId(checkQualityProblem.getId()));
		RestResponseElement response = new RestResponseElement();
		response.setElement(entityVo);
		return response;
	}

	@Override
	public void processAddEntity(CheckQualityProblemFormVo form, CheckQualityProblem entity) throws JsonProcessingException {
		ObjectMapper mapper = new ObjectMapper();
		ProblemClass problemClass = problemClassRepository.findOne(form.problemClassId);
		if(problemClass.getParentProblemClass().getProblemClassName().equals("工程亮点")) {
			entity.setStatus(ProblemStatus.已通过);
			entity.setRepairBy(userRepository.findOne(form.registBy));
			entity.setRepairDate(new Date());
			entity.setReinspectBy(userRepository.findOne(form.registBy));
			entity.setReinspectCompletedDate(new Date());
			form.repairs = Arrays.asList(form.registBy);
			form.reinspects = Arrays.asList(form.registBy);
		} else {
			entity.setStatus(ProblemStatus.待整改);
		}
		entity.setCheckQualityBatch(checkQualityBatchRepository.findOne(form.batchId));
		entity.setBuilding(buildingRepository.findOne(form.buildingId));
		entity.setUnit(unitRepository.findOne(form.unitId));
		entity.setFloor(floorRepository.findOne(form.floorId));
		entity.setHouse(houseRepository.findOne(form.houseId));
		entity.setPlace(form.place);
		entity.setProblemClass(problemClass);
		entity.setProblem(problemRepository.findOne(form.problemId));
		entity.setRegistBy(userRepository.findOne(form.registBy));
		entity.setRemark(form.remark);
		entity.setRegistDate(new Date());
		entity.setRepairDeadline(DateUtils.addDay(new Date(), form.days));
		entity.setImageFile(mapper.writeValueAsString(form.photos));
		entity.setContractor(contractorRepository.findOne(form.contractorId));
		entity.setEmergencyDegree(form.emergencyDegree);
		entity.setProblemValues(mapper.writeValueAsString(form.problemValues));
		getRepository().saveAndFlush(entity);
		
		form.repairs.forEach(repairUserId -> {
			CheckQualityRepair checkQualityRepair = new CheckQualityRepair();
			checkQualityRepair.setCheckQualityProblem(entity);
			checkQualityRepair.setRepair(userRepository.findOne(repairUserId));
			checkQualityRepairRepository.saveAndFlush(checkQualityRepair);
		});
		
		form.reinspects.forEach(reinspectsUserId -> {
			CheckQualityReinspect checkQualityReinspect = new CheckQualityReinspect();
			checkQualityReinspect.setCheckQualityProblem(entity);
			checkQualityReinspect.setReinspect(userRepository.findOne(reinspectsUserId));
			checkQualityReinspectRepository.saveAndFlush(checkQualityReinspect);
		});
		
		form.ccs.forEach(ccUserId -> {
			CheckQualityCc checkQualityCc = new CheckQualityCc();
			checkQualityCc.setCheckQualityProblem(entity);
			checkQualityCc.setCc(userRepository.findOne(ccUserId));
			checkQualityCcRepository.saveAndFlush(checkQualityCc);
		});
	}
}
